#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>

/*
    对线程进行一个简单的封装
*/

// 回调方法：具体情况而定
using callback_ = std::function<void(int)>;
using callback = std::function<void(void*)>;
enum class  STATUS
{
    EXIT,
    RUNNING,
    NEW
};
using std::cout;
using std::endl;
class Thread
{
public: 

    enum class MODE
    {
        DETACH,
        JOIN
    };

    Thread()
    {}

    Thread(callback cb,int num,void* args,MODE mod = MODE::JOIN)
    :_cb(cb)
    ,_num(num)
    ,_args(args)
    ,_mod(mod)
    {
        _name = "线程" + std::to_string(num); 
        _st = STATUS::NEW;
        // create();
    }



    Thread(callback_ cb,std::string name,void* args,MODE mod = MODE::JOIN)
    :_ccb(cb)
    ,_args(args)
    ,_mod(mod)
    ,_name(name)
    {
        _st = STATUS::NEW;
        // create();
    }

    // 线程的入口函数，需要设计成static
    // 类内函数存在隐藏的this指针
    // 传递this指针，以便于调用类内成员
    static void* threadRoutinue(void* args)
    {
        
        Thread* pthis = static_cast<Thread*>(args);
        // if(pthis->_mod == MODE::DETACH)
        // {
        //     pthis->detach();
        // }
        // 对()进行一个重载
        // pthis->_cb();
        (*pthis)();
        return nullptr;
    }
    void operator()()
    {
        cout << "args = " << *(int*)_args << endl;
        int fd = *(int*)_args;
        cout << "this = "<< this << endl;
        _ccb(fd);
        cout << "-----------" << endl;

        // _cb(_args);
    }

    void detach()
    {
        pthread_detach(_tid);
    }
    
    void create()
    {
        //创建线程
        pthread_create(&_tid,nullptr,threadRoutinue,(void*)this);
        _st = STATUS::RUNNING;
        std::cout <<  _name << "启动成功" << std::endl;
        if(_mod == MODE::DETACH)
        {
            detach();
            
        }
    }

    void cancel()
    {
        pthread_cancel(_tid);
        _st = STATUS::EXIT;
    }
    
    void join()
    {
        if(_mod == MODE::JOIN)
            pthread_join(_tid,nullptr);
        _st = STATUS::EXIT;
    }
    
    pthread_t getTid()
    {
        if(_st == STATUS::RUNNING)
            return _tid;
        else    
            return 0;
    }

    std::string getName()
    {
        return _name;
    }
    MODE getType()
    {
        return _mod;
    }
    ~Thread()
    {}
    
private:
    // 线程自身的属性
    STATUS _st;
    int _num; // 线程编号
    std::string _name; //线程名字
    pthread_t _tid;
    MODE _mod;

    // 回调函数的参数
    // 线程执行的任务可能需要参数
    void* _args;
    // 线程执行的方法，但不是入口函数
    callback _cb; 
    callback_ _ccb;
    // 线程执行任务的结果
    int _res;
    int _errno;
    std::string _errstr; 
};
